<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from "vue";
import { useI18n } from 'vue-i18n';
import { useFloatingPanel } from '../composables/useFloatingPanel';
import { useCombobox } from '../composables/useCombobox';

// i18n at top
const { t } = useI18n();

const props = defineProps({
  keys: { type: Array, default: () => [] },
  modelKey: { type: String, default: "" },
  sending: { type: Boolean, default: false },
});
const emit = defineEmits(["update:modelKey", "send", "cancel"]);

const text = ref("");

// 立即切换发送态的本地 pending，避免父 prop 传递延迟造成按钮空窗
const localPending = ref(false);
const sendingUI = computed(() => props.sending || localPending.value);
watch(() => props.sending, (now) => {
  if (!now) {
    // 结束发送后，复位本地 pending
    localPending.value = false;
  }
}, { immediate: true });

// combobox state via composable
const boxRef = ref(null);
const panelRef = ref(null);

const {
  open,
  query,
  highlightIndex,
  filteredItems: filteredKeys,
  openMenu,
  closeMenu,
  onKeyNav,
} = useCombobox({ items: computed(() => Array.isArray(props.keys) ? props.keys : []) });

const displayPlaceholder = computed(() => props.modelKey || '选择模型键');

function chooseKey(k) {
  if (!k) return;
  emit("update:modelKey", k);
  query.value = "";
  closeMenu();
}

function onDocClick(ev) {
  if (!open.value) return;
  if (!boxRef.value) return;
  const inTrigger = boxRef.value.contains(ev.target);
  const inPanel = panelRef.value ? panelRef.value.contains(ev.target) : false;
  if (!inTrigger && !inPanel) closeMenu();
}

// floating panel via composable
const { position, startTracking, stopTracking, scheduleReposition } = useFloatingPanel(boxRef, panelRef, { placement: 'auto', margin: 8, offset: 4 });

function onWindowMove() {
  if (open.value) scheduleReposition();
}

onMounted(() => {
  document.addEventListener("mousedown", onDocClick);
  window.addEventListener("scroll", onWindowMove, { passive: true });
  window.addEventListener("resize", onWindowMove, { passive: true });
});

onBeforeUnmount(() => {
  document.removeEventListener("mousedown", onDocClick);
  window.removeEventListener("scroll", onWindowMove);
  window.removeEventListener("resize", onWindowMove);
});

// when opening menu, trigger a reposition and start tracking lifecycle
function openMenuAndTrack() {
  openMenu();
  nextTick(() => {
    startTracking();
    requestAnimationFrame(() => {
      const el = document.querySelector('[data-combobox-search="1"]');
      if (el) el.focus();
      scheduleReposition();
    });
  });
}

function closeMenuAndStop() {
  closeMenu();
  stopTracking();
}

function onSend() {
  const value = text.value.trim();
  if (!value) return;
  
  // 立即进入发送 UI 态（对所有情况都设置，保持一致性）
  localPending.value = true;
  emit("send", value);
  
  // 若有模型键，则清空输入
  if (props.modelKey) {
    text.value = "";
  }
  // 注意：如果没有模型键，保持输入内容，让用户可以看到错误信息后重试
}

function onCancel() {
  // 重置本地 pending 状态
  localPending.value = false;
  emit("cancel");
}

// 暴露text属性，允许父组件直接访问和修改输入框内容
defineExpose({
  text
});
</script>

<template>
  <div class="rounded-lg border border-slate-200 bg-white p-2 shadow-sm dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-300">
    <textarea
      class="block w-full resize-none rounded-md bg-transparent px-2 py-2 text-[13px] text-slate-900 placeholder-slate-400 focus:outline-none focus:ring-0 dark:text-neutral-300 dark:placeholder-neutral-500"
      rows="4"
      :disabled="sendingUI"
      v-model="text"
      :placeholder="t('app.input_placeholder')"
      @keydown.enter.prevent="onSend"
    />

    <!-- 底部工具栏：左侧模型键选择 / 右侧发送或取消 -->
    <div class="mt-2 flex items-center justify-between">
      <div class="" ref="boxRef">
        <div class="relative">
          <button
            type="button"
            class="inline-flex h-6 min-w-[80px] items-center justify-between rounded px-2 text-[11px] text-slate-600 hover:text-slate-800 focus:outline-none dark:text-neutral-400 dark:hover:text-neutral-200"
            @click="open ? closeMenuAndStop() : openMenuAndTrack()"
            aria-haspopup="listbox"
            :aria-expanded="open"
          >
            <span class="truncate" :class="modelKey ? '' : 'text-slate-500 dark:text-neutral-400'">{{ displayPlaceholder }}</span>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" class="h-3 w-3 text-slate-500 dark:text-neutral-400">
              <path d="M6 9l6 6 6-6"/>
            </svg>
          </button>
        </div>
      </div>

      <!-- Teleport 面板，完全覆盖式定位，不挤压布局 -->
      <teleport to="body">
        <div v-if="open" ref="panelRef" class="fixed z-[1000] overflow-hidden rounded-md border border-slate-200 bg-white shadow-lg dark:border-neutral-800 dark:bg-neutral-900"
             :style="{ left: position.left + 'px', top: position.top + 'px', minWidth: '200px', maxWidth: 'calc(100vw - 16px)' }">
          <div class="flex h-8 items-center gap-1 border-b border-slate-200 px-2 text-[12px] dark:border-neutral-800">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" class="h-3.5 w-3.5 text-slate-500 dark:text-neutral-400"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
            <input
              class="h-full w-full bg-transparent text-[12px] text-slate-900 placeholder-slate-400 outline-none dark:text-neutral-100 dark:placeholder-neutral-500"
              placeholder="筛选键名..."
              v-model="query"
              @keydown="onKeyNav($event, chooseKey)"
              data-combobox-search="1"
            />
          </div>
          <ul role="listbox" class="max-h-60 overflow-auto py-0 text-[12px] whitespace-nowrap">
            <li
              v-for="(k, idx) in filteredKeys"
              :key="k"
              :aria-selected="modelKey === k"
              @mouseenter="highlightIndex = idx"
              @mousedown.prevent="chooseKey(k)"
              class="flex h-8 cursor-pointer items-center px-2 text-slate-700 dark:text-neutral-200"
              :class="[
                'hover:bg-slate-100 dark:hover:bg-neutral-800',
                (idx === highlightIndex || modelKey === k)
                  ? 'bg-slate-100 dark:bg-neutral-800 mx-1 my-0.5 rounded-md'
                  : ''
              ]"
            >
              {{ k }}
            </li>
            <li v-if="!filteredKeys.length" class="flex h-8 items-center px-2 text-[12px] text-slate-400 dark:text-neutral-500">无匹配结果</li>
          </ul>
        </div>
      </teleport>

      <div class="flex items-center gap-2">
        <div id="send-button-status" class="sr-only">
          {{ sendingUI ? '正在发送消息，点击可取消' : (text.trim() ? '准备发送消息' : '请输入消息内容') }}
        </div>
        <button
          role="button"
          class="inline-flex h-6 w-6 items-center justify-center rounded border border-transparent transition disabled:opacity-50"
          :class="sendingUI ? 'bg-red-600 text-white hover:bg-red-500' : 'bg-indigo-600 text-white hover:bg-indigo-500'"
          :disabled="!sendingUI && !text.trim()"
          @click="sendingUI ? onCancel() : onSend()"
          :aria-label="sendingUI ? '取消发送' : '发送消息'"
          :aria-describedby="'send-button-status'"
          :aria-pressed="sendingUI ? 'true' : 'false'"
          :title="sendingUI ? '停止发送' : '发送消息'"
        >
          <!-- 停止图标 -->
          <svg v-if="sendingUI" viewBox="0 0 24 24" fill="currentColor" class="h-3 w-3">
            <rect x="6" y="6" width="12" height="12" rx="2" />
          </svg>
          <!-- 发送图标 -->
          <svg v-else viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-3 w-3">
            <path d="M22 2L11 13" />
            <path d="M22 2L15 22L11 13L2 9L22 2Z" />
          </svg>
        </button>
      </div>
    </div>
  </div>
</template>



